package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.tanhua.autoconfig.templates.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.db.Question;
import com.tanhua.model.db.Settings;
import com.tanhua.model.db.User;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.*;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;


@Service
public class UsersService {

    @DubboReference
    private UserInfoApi userInfoApi;
    @DubboReference
    private QuestionApi questionApi;
    @DubboReference
    private SettingsApi settingsApi;
    @DubboReference
    private BlackListApi blackListApi;
    @DubboReference
    private UserApi userApi;
    @DubboReference
    private UserLikeApi userLikeApi;
    @DubboReference
    private VisitorsApi visitorsApi;
    @DubboReference
    private FriendApi friendApi;
    @Autowired
    private StringRedisTemplate  redisTemplate;
    @Autowired
    private HuanXinTemplate huanXinTemplate;

    //根据id;
    public UserInfoVo findUserInfoById(Long userId) {
        //需要调用公共的api接口
        UserInfo info = userInfoApi.findById(userId);
        //将查询到的info对象转换成对应的vo对象,在数据库当中的age是Integer类型的，在接口文档中要求的是String类型
        //2.构建一个Vo对象
        UserInfoVo vo = new UserInfoVo();
        //3.使用工具类来将对象中的数据进行赋值
        if (ObjectUtil.isNotNull(info)){
            BeanUtils.copyProperties(info, vo);
        }
        //4.如果info对象的年龄字段不为空，就进行类型转换再赋值
        if (ObjectUtil.isNotNull(info.getAge())) {
            vo.setAge(info.getAge().toString());
        }
        return vo;
    }

    //更新用户数据
    public void update(UserInfo userInfo) {
        //调用公共的接口来进行保存
        userInfoApi.update(userInfo);
    }

    //查询通用设置
    public SettingsVo settings() {
        //0.先准备好一个vo对象
        SettingsVo vo = new SettingsVo();
        //1.从ThreadLocal中获取到userId
        Long userId = UserHolder.getUserId();
        //2.查询陌生人问题(根据用户id来查询)
        Question question = questionApi.findByUserId(userId);
        String txt = question == null ? "你喜欢java吗？":question.getTxt();
        vo.setStrangerQuestion(txt);
        //3.查询通用设置开关
        Settings settings=settingsApi.findByUserId(userId);
        if(settings!=null){
            vo.setGonggaoNotification(settings.getGonggaoNotification());
            vo.setLikeNotification(settings.getLikeNotification());
            vo.setPinglunNotification(settings.getPinglunNotification());
        }
        //4.获取当前用户的手机号
        String mobile = UserHolder.getUser().getMobile();
        vo.setPhone(mobile);
        vo.setId(userId);
        //4.返回结果
        return vo;
    }

    //保存陌生人问题
    public void questions(String content) {
        //1.获取用户id,根据id来保存
        Long userId = UserHolder.getUserId();
        //2.查询陌生人问题
        Question question = questionApi.findByUserId(userId);
        if (question==null){
            //3.如果没有陌生人问题
            question = new Question();
            question.setUserId(userId);
            question.setTxt(content);
            questionApi.save(question);
        }else{
            //4.有陌生人问题,就更新
            question.setTxt(content);
            questionApi.update(question);
        }

    }

    //保存和更新通用开关
    public void setting(Boolean like, Boolean pinglun, Boolean gonggao) {
        //1.获取用户id
        Long userId = UserHolder.getUserId();
        //2.查询开关对象
        Settings settings = settingsApi.findByUserId(userId);
        //3.判断开关对象是否存在
        if(settings==null){
            //4.如果对象不存在,就进行保存
            settings=new Settings();
            settings.setLikeNotification(like);
            settings.setPinglunNotification(pinglun);
            settings.setGonggaoNotification(gonggao);
            settings.setUserId(userId);
            settingsApi.save(settings);
        }else{
            //5.如果存在,就进行更新
            settings.setLikeNotification(like);
            settings.setPinglunNotification(pinglun);
            settings.setGonggaoNotification(gonggao);
            settingsApi.update(settings);
        }
    }

    //分页查询黑名单设置
    public PageResult blacklist(Integer page, Integer pagesize) {
        //1.获取用户id
        Long userId = UserHolder.getUserId();
        //2.调用API查询用户黑名单,这里返回一个分页对象,然后将分页对象返回
        IPage<UserInfo> iPage=blackListApi.findByPage(userId,page,pagesize);
        //3.使用PageResult中提供的构造方法
        return new PageResult(page,pagesize,iPage.getTotal(),iPage.getRecords());
    }

    //移除黑名单
    public void delete(String uid) {
        //1.获取当前用户的id
        Long userId = UserHolder.getUserId();
        //2.根据当前用户的id和要移除的黑名单用户id进行删除
        blackListApi.delete(userId,uid);
    }

    //修改手机号1-发送验证码
    public void sendVerificationCode() {
        //1.获取到手机号
        Long userId = UserHolder.getUserId();
        User user=userApi.findById(userId);
            //获取到手机号
            String mobile = user.getMobile();
        //2.构建出验证码
        String code="123456";
        //3.将验证码存到redis当中
        redisTemplate.opsForValue().set("CODE_"+mobile,code,5, TimeUnit.MINUTES);
    }

    //修改手机号1-发送验证码
    public Map verificationCode(String code) {
        //1.根据id获取到手机号
        User user = userApi.findById(UserHolder.getUserId());
        String mobile = user.getMobile();
        //2.从redis当中获取验证码
        String redisCode = redisTemplate.opsForValue().get("CODE_" + mobile);
        //3.对验证码进行校验
        Boolean codeBoolean=true;
        if (StringUtils.isEmpty(code)||!redisCode.equals(code)){
            codeBoolean=false;
            //4.不一致就抛出异常
            throw new BusinessException(ErrorResult.loginError());
        }
         //5.一致，就删除redis中的验证码数据
        redisTemplate.delete("CODE_" + mobile);
         Map<String, Boolean> map = new HashMap<>();
         map.put("verification",codeBoolean);
        return map;
    }

    //修改手机号第三步，保存手机号
    public void updatePhone(String phone) {
        //1.获取到全部的用户信息
        List<User> users = userApi.findAll();
        //2.提取users中的所有手机号
        List<String> phones = CollUtil.getFieldValues(users, "phone", String.class);
        //3.校验一下该号码是否在用户的号码集合当中
        boolean contains = phones.contains(phone);
        if (contains){
            //如果存在，就抛出手机号码已注册的异常
            throw new BusinessException(ErrorResult.mobileError());
        }
        //4.如果不存在，就将号码更新到数据库当中
        User user = new User();
        user.setId(UserHolder.getUserId());
        user.setMobile(phone);
        userApi.updatePhoneById(user);
    }
    //互相喜欢 eachLoveCount   喜欢 loveCount   粉丝 fanCount
    //统计
    public UserLikeVo counts() {

        //获取当前登录用户id
        Long userId = UserHolder.getUserId();
        //key
        String key = "likeCount";
        String hashKey = Constants.USER_LIKE_KEY + userId;
        String value = (String) redisTemplate.opsForHash().get(key, hashKey);

        UserLikeVo vo = userLikeApi.counts(userId);

        if (value == null) {
            Integer fanCount = vo.getFanCount();
            Integer loveCount = vo.getLoveCount();
            Integer eachLoveCount = vo.getEachLoveCount();

            String count = fanCount + "," + loveCount + "," + eachLoveCount;
            redisTemplate.opsForHash().put(key, hashKey, count);
        } else {
            String[] split = value.split(",");
            vo = new UserLikeVo();
            vo.setFanCount(Integer.valueOf(split[0]));
            vo.setLoveCount(Integer.valueOf(split[1]));
            vo.setEachLoveCount(Integer.valueOf(Integer.valueOf(split[2])));

            redisTemplate.opsForHash().delete(key, hashKey);
        }
        return vo;
    }
    //互相喜欢、喜欢、粉丝、谁看过我 - 翻页列表
    public PageResult pageList(Integer type, Integer page, Integer pagesize, String nickname) {
        //当前登录用户id
        Long userId = UserHolder.getUserId();
        PageResult pr = new PageResult();
        //调用userInfo查询好友用户详情
        UserInfo info = new UserInfo();
        info.setNickname(nickname);

        switch (type) {
            // 互相喜欢
            case 1:
                //调用api查询当前好友数据
                List<UserLike> list1 = userLikeApi.findLove(page, pagesize, userId);
                if (list1 == null) {
                    return new PageResult();
                }
                List<UserTypeVo> vos = new ArrayList<>();
                //提取数据列表中的id
                List<Long> userIds = CollUtil.getFieldValues(list1, "userId", Long.class);

                Map<Long, UserInfo> map = userInfoApi.findByIds(userIds);

                for (UserLike userLike : list1) {
                    UserInfo userInfo = map.get(userLike.getUserId());
                    if (userInfo != null) {
                        UserTypeVo vo = new UserTypeVo();
                        BeanUtils.copyProperties(userInfo, vo);
                        vo.setMatchRate(96);
                        vo.setAlreadyLove(true);
                        vos.add(vo);
                    }
                }
                pr = new PageResult(page, pagesize, 0L, vos);
                break;
            // 我喜欢的
            case 2:
                List<UserLike> list2 = userLikeApi.findILove(page, pagesize, userId);
                if (list2 == null) {
                    return new PageResult();
                }
                List<UserTypeVo> vos2 = new ArrayList<>();
                List<Long> likeUserId = CollUtil.getFieldValues(list2, "likeUserId", Long.class);
                Map<Long, UserInfo> map2 = userInfoApi.findByIds(likeUserId);
                for (UserLike userLike : list2) {
                    UserInfo userInfo = map2.get(userLike.getLikeUserId());
                    if (userInfo != null) {
                        UserTypeVo vo2 = new UserTypeVo();
                        BeanUtils.copyProperties(userInfo, vo2);
                        vo2.setMatchRate(96);
                        vo2.setAlreadyLove(true);
                        vos2.add(vo2);
                    }
                }
                pr = new PageResult(page, pagesize, 0L, vos2);
                break;
            // 喜欢我的
            case 3:
                List<UserLike> list3 = userLikeApi.findLoveI(page, pagesize, userId);
                if (list3 == null) {
                    return new PageResult();
                }
                List<Long> likeUserId1 = CollUtil.getFieldValues(list3, "userId", Long.class);
                Map<Long, UserInfo> map3 = userInfoApi.findByIds(likeUserId1);
                List<UserTypeVo> vos3 = new ArrayList<>();
                for (UserLike userLike : list3) {
                    UserInfo userInfo = map3.get(userLike.getUserId());
                    if (userInfo != null) {
                        UserTypeVo vo3 = new UserTypeVo();
                        BeanUtils.copyProperties(userInfo, vo3);
                        vo3.setMatchRate(96);
                        boolean flag = userLikeApi.iLove(userId, userLike.getUserId());
                        vo3.setAlreadyLove(flag);
                        vos3.add(vo3);
                    }
                }
                pr = new PageResult(page, pagesize, 0L, vos3);
                break;
            //谁看过我
            default:
                List<Visitors> list4 = visitorsApi.lookMe(page, pagesize, userId);
                if (list4 == null) {
                    return new PageResult();
                }
                List<UserTypeVo> vos4 = new ArrayList<>();
                List<Long> visitorUserId = CollUtil.getFieldValues(list4, "visitorUserId", Long.class);

                Map<Long, UserInfo> map4 = userInfoApi.findByIds(visitorUserId);
                for (Visitors visitors : list4) {
                    UserInfo userInfo = map4.get(visitors.getVisitorUserId());
                    if (userInfo != null) {
                        UserTypeVo vo4 = new UserTypeVo();
                        BeanUtils.copyProperties(userInfo, vo4);
                        vo4.setMatchRate(96);
                        boolean flag = userLikeApi.iLove(userId, visitors.getUserId());
                        vo4.setAlreadyLove(flag);
                        vos4.add(vo4);
                    }
                }
                pr = new PageResult(page, pagesize, 0L, vos4);
                break;
        }
        return pr;

    }

    //关注
    public void fansLike(Long likeUserId) {
        //保存数据到数据库
        Long userId = UserHolder.getUserId();
        Boolean aBoolean = userLikeApi.saveOrUpdate(userId, likeUserId, true);
        if (!aBoolean) {
            throw new BusinessException(ErrorResult.error());
        }
        //将数据保存到redis中 并删除不喜欢的redis内容
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY + userId, likeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + userId, likeUserId.toString());
        //判断是否双向喜欢 如果是 则添加好友
        Boolean flag = userLikeApi.TwoWayRush(userId, likeUserId, true);
        if (flag) {
            friendApi.save(userId, likeUserId);
        }
        //添加环信好友
        Boolean addHuanxin = huanXinTemplate.addContact(Constants.HX_USER_PREFIX + userId, Constants.HX_USER_PREFIX + likeUserId);
    }

    //不关注
    public void fansUnLike(Long unLikeUserId) {
        Long userId = UserHolder.getUserId();
        //判断是否双向喜欢 如果是 则删除环信以及探花好友
        Boolean flag = userLikeApi.TwoWayRush(userId, unLikeUserId, true);
        if (flag) {
            Boolean deleteHuanxin = huanXinTemplate.deleteContact(Constants.HX_USER_PREFIX + userId, Constants.HX_USER_PREFIX + unLikeUserId);
            friendApi.deleteFriends(unLikeUserId, userId);
        }
        //删除userLike表中喜欢的数据
        Boolean delete = userLikeApi.deleteById(userId, unLikeUserId, true);
        if (!delete) {
            throw new BusinessException(ErrorResult.error());
        }
        //删除喜欢的redis数据
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + userId, unLikeUserId.toString());
    }

}

